package com.rzgeo.wcgallay;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.NavigationView;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;

import com.esri.arcgisruntime.concurrent.ListenableFuture;
import com.esri.arcgisruntime.geometry.Envelope;
import com.esri.arcgisruntime.geometry.Point;
import com.esri.arcgisruntime.layers.ArcGISTiledLayer;
import com.esri.arcgisruntime.layers.FeatureLayer;
import com.esri.arcgisruntime.layers.Layer;
import com.esri.arcgisruntime.mapping.ArcGISMap;
import com.esri.arcgisruntime.mapping.ArcGISScene;
import com.esri.arcgisruntime.mapping.Basemap;
import com.esri.arcgisruntime.mapping.LayerList;
import com.esri.arcgisruntime.mapping.RasterElevationSource;
import com.esri.arcgisruntime.mapping.view.Camera;
import com.esri.arcgisruntime.mapping.view.DefaultMapViewOnTouchListener;
import com.esri.arcgisruntime.mapping.view.DefaultSceneViewOnTouchListener;
import com.esri.arcgisruntime.mapping.view.GeoView;
import com.esri.arcgisruntime.mapping.view.GraphicsOverlay;
import com.esri.arcgisruntime.mapping.view.IdentifyLayerResult;
import com.esri.arcgisruntime.mapping.view.MapView;
import com.esri.arcgisruntime.mapping.view.SceneView;
import com.esri.arcgisruntime.util.ListenableList;
import com.rzgeo.rzmaplib.comp.RmlMarkList;
import com.rzgeo.rzmaplib.comp.RmlSlideList;
import com.rzgeo.rzmaplib.util.RmlUtil;
import com.rzgeo.wcgallay.comp.Wcm3DConf;
import com.rzgeo.wcgallay.comp.WcmPanel;
import com.rzgeo.wcgallay.comp.WcmReseDetail;
import com.rzgeo.wcgallay.comp.WcmReseGallary;
import com.rzgeo.wcgallay.model.WcmMapModel;
import com.rzgeo.wcgallay.model.WcmMapTool;
import com.rzgeo.wcgallay.util.WcmUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;

public class WcmSceneActv extends AppCompatActivity
        implements NavigationView.OnNavigationItemSelectedListener {

    private String userName;
    //    private SceneView _sceneView;
//    private MapView _mapView;
    private WcmMapModel _mapModel;
    private WcmReseGallary _reseGallary;
    private WcmReseDetail _reseDetail;
    private String _prjName;
    private Wcm3DConf _c3dEffcet;
    private WcmPanel _llLeft;
    private WcmPanel _llRight;
    private String _mapMode;
    private GeoViewHolder _geoViewHolder;
    private WcmMapTool _mapTool;
    private RmlMarkList _cReseMarkerList;
    private RmlSlideList _cReseSlideList;
    private static final int RequstCode2Chart=201;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.actv_scene);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

//        DrawerLayout drawer = findViewById(R.id.drawer_layout);
//        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
//                this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
//        drawer.addDrawerListener(toggle);
//        toggle.syncState();

//        NavigationView navigationView = findViewById(R.id.nav_view);
//        //左侧弹出
//        navigationView.setNavigationItemSelectedListener(this);

        userName = getIntent().getStringExtra("USERNAME");
        _prjName = getIntent().getStringExtra("PRJNAME");

        _reseGallary = findViewById(R.id.c_rese_gallary);
        _reseDetail = findViewById(R.id.c_rese_detail);
        _c3dEffcet = findViewById(R.id.c_3d_effcet);
        _cReseMarkerList = findViewById(R.id.c_rese_marker);
        _cReseSlideList = findViewById(R.id.c_rese_slides);


        _llLeft = findViewById(R.id.ll_left);
        _llRight = findViewById(R.id.ll_right);

        if (WcmMapModel.V2DMap.equalsIgnoreCase(
                getIntent().getStringExtra(WcmMapModel.KMapMode)
        )) {
            MapView mapView = findViewById(R.id.mapView);
            mapView.setVisibility(View.VISIBLE);

            _geoViewHolder = new GeoViewHolder(this, null, mapView);
        } else {
            SceneView sceneView = findViewById(R.id.sceneView);
            sceneView.setVisibility(View.VISIBLE);

            _geoViewHolder = new GeoViewHolder(this, sceneView, null);
            _c3dEffcet.setup(sceneView);
        }
        _mapMode = getIntent().getStringExtra(WcmMapModel.KMapMode);


        _mapModel = new WcmMapModel(
                this,
                _geoViewHolder,
                _prjName,
                _reseGallary,
                _reseDetail,
                _cReseMarkerList,
                _cReseSlideList);
        _mapTool = new WcmMapTool(_geoViewHolder.getGeoView(), this);


        _llLeft.setup(findViewById(R.id.btn_fold_left));
        _llRight.setup(findViewById(R.id.btn_fold_right));

        _llLeft.setOnSelect(_reseGallary.getId());

    }

    @Override
    public void onBackPressed() {
        DrawerLayout drawer = findViewById(R.id.drawer_layout);
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawer(GravityCompat.START);
        } else {
            super.onBackPressed();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.map_actv, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        int menuId = item.getItemId();

        if (menuId == R.id.act_3d2d) {
//            if(item.getTitle().equals(getString(R.string.l_23d))){
//                item.setTitle(R.string.l_2d);
//                item.setIcon(R.drawable.ica_to2d);
//
//                _mapView.setVisibility(View.VISIBLE);
//                _sceneView.setVisibility(View.VISIBLE);
//            }
//            else if(item.getTitle().equals(getString(R.string.l_2d))){
//                item.setTitle(R.string.l_3d);
//                item.setIcon(R.drawable.ica_to3d);
//
//                _mapView.setVisibility(View.VISIBLE);
//                _sceneView.setVisibility(View.GONE);
//            }
//            else if(item.getTitle().equals(getString(R.string.l_3d))){
//                item.setTitle(R.string.l_23d);
//                item.setIcon(R.drawable.ica_to2_3d);
//
//                _mapView.setVisibility(View.GONE);
//                _sceneView.setVisibility(View.VISIBLE);
//            }

        }else if(menuId == R.id.act_chart){
            Intent intent = new Intent();
            intent.putExtra(WcmChartActv.StartInfo.Key,_mapModel.getStartInfo());
            intent.setClass(WcmSceneActv.this, WcmChartActv.class);
            startActivityForResult(intent, RequstCode2Chart);
        }
        else if(menuId == R.id.act_screenshot){
            _mapTool.screenShot(new RmlUtil.Dialog.OnResult() {
                @Override
                public void OnResult(boolean sucess) {

                }
            });
        }else {
            int viewId = -1;

            if (menuId == R.id.act_gallay) {
                viewId = _reseGallary.getId();
            }
            if (menuId == R.id.act_detail) {
                viewId = _reseDetail.getId();
            }
            if (menuId == R.id.act_effect) {
                if (_c3dEffcet.isValid())
                    viewId = _c3dEffcet.getId();
                else
                    WcmUtil.Tip.Toast("当前模式下3D效果设置不可用");
            }
            if (menuId == R.id.act_marker) {
                viewId = _cReseMarkerList.getId();
            } else if (menuId == R.id.act_settings) {
                return true;
            }

            _llLeft.setOnSelect(viewId);
            _llRight.setOnSelect(viewId);
        }

//        if (id == R.id.act_gallay) {
//            if (_reseGallary.getVisibility() != View.VISIBLE) {
//                _reseGallary.setVisibility(View.VISIBLE);
//            } else {
//                _reseGallary.setVisibility(View.GONE);
//            }
//            return true;
//        }
//        if (id == R.id.act_detail) {
//            if (_reseDetail.getVisibility() != View.VISIBLE) {
//                _reseDetail.setVisibility(View.VISIBLE);
//            } else {
//                _reseDetail.setVisibility(View.GONE);
//            }
//        } else if (id == R.id.act_settings) {
//            return true;
//        }

        return super.onOptionsItemSelected(item);
    }

    @SuppressWarnings("StatementWithEmptyBody")
    @Override
    public boolean onNavigationItemSelected(MenuItem item) {
        // Handle navigation view item clicks here.
        int id = item.getItemId();

        if (id == R.id.nav_screen_shot_save) {
            // Handle the camera action
            _mapTool.screenShot(new RmlUtil.Dialog.OnResult() {
                @Override
                public void OnResult(boolean sucess) {

                }
            });
        } else if (id == R.id.nav_bookmark) {


        } else if (id == R.id.nav_manage) {

        } else if (id == R.id.nav_share) {

        } else if (id == R.id.nav_send) {

        }

        DrawerLayout drawer = findViewById(R.id.drawer_layout);
        drawer.closeDrawer(GravityCompat.START);
        return true;
    }

    private class GeoViewHolder implements com.rzgeo.wcgallay.model.GeoViewHolder {

        private SceneView _sceneView;
        private MapView _mapView;
        private View.OnTouchListener _onSceneViewListener;
        private View.OnTouchListener _onMapViewListener;
        private OnTouchListener _onTouchListener;

        public GeoViewHolder(Context context, SceneView sceneView, MapView mapView) {
            _sceneView = sceneView;
            _mapView = mapView;

            if (_sceneView != null) {
                _onSceneViewListener = new DefaultSceneViewOnTouchListener(sceneView) {
                    @Override
                    public boolean onSingleTapConfirmed(MotionEvent e) {
                        if (_onTouchListener != null) {
                            android.graphics.Point sp = new android.graphics.Point((int) e.getX(), (int) e.getY());
                            Point mp = _sceneView.screenToBaseSurface(sp);
                            identify(mp, sp, e);
                        }
                        return super.onSingleTapConfirmed(e);
                    }
                };

                _sceneView.setOnTouchListener(_onSceneViewListener);
            }

            if (_mapView != null) {

                _onMapViewListener = new DefaultMapViewOnTouchListener(context, mapView) {
                    @Override
                    public boolean onSingleTapConfirmed(MotionEvent e) {
                        if (_onTouchListener != null) {
                            android.graphics.Point sp = new android.graphics.Point((int) e.getX(), (int) e.getY());
                            Point mp = _mapView.screenToLocation(sp);
                            identify(mp, sp, e);
                        }
                        return super.onSingleTapConfirmed(e);
                    }
                };
                _mapView.setOnTouchListener(_onMapViewListener);
            }
        }

        private void identify(final Point mp, final android.graphics.Point sp, MotionEvent e) {

            final ListenableFuture<IdentifyLayerResult> identifyFuture =
                    getGeoView().identifyLayerAsync(_onTouchListener.wantLayer(), sp,
                            _onTouchListener.getTolerance(),
                            false,
                            _onTouchListener.getMaxReturn());
            identifyFuture.addDoneListener(new Runnable() {

                @Override
                public void run() {
                    try {
                        IdentifyLayerResult identifyLayerResult = identifyFuture.get();
                        _onTouchListener.onTouch(
                                mp, sp,
                                identifyLayerResult.getElements()
                        );
                        _onTouchListener = null;
                    } catch (InterruptedException | ExecutionException e) {
                        // must deal with checked exceptions thrown from the async identify operation
                        RmlUtil.Log.Err(e);
                    }
                }
            });
        }

        @Override
        public void addGraphicsOverlay(GraphicsOverlay gls) {
            if (_sceneView != null) {
                _sceneView.getGraphicsOverlays().add(gls);
            } else if (_mapView != null) {
                _mapView.getGraphicsOverlays().add(gls);
            }
        }

        @Override
        public void setViewPoint(Point llPoint) {
            if (_sceneView != null) {
                Camera camera = new Camera(llPoint, 4500, 0, 30, 0);
                _sceneView.setViewpointCameraAsync(camera);
            } else if (_mapView != null) {
                _mapView.setViewpointCenterAsync(llPoint, 50000);
            }
        }

        @Override
        public void setViewExtent(Envelope ext) {
            if (_sceneView != null) {
                Camera camera = new Camera(ext.getCenter(), 4500, 0, 30, 0);
                _sceneView.setViewpointCameraAsync(camera);
            } else if (_mapView != null) {
                _mapView.setViewpointGeometryAsync(ext, 0.5);
            }
        }

        @Override
        public void setBaseMap(ArcGISTiledLayer tlayer, final String elevationSourcePath) {

            if (_sceneView != null) {
                ArcGISScene scene = new ArcGISScene(new Basemap(tlayer));
                if (elevationSourcePath != null) {
                    ArrayList<String> fs = new ArrayList<String>() {{
                        add(elevationSourcePath);
                    }};
                    scene.getBaseSurface().getElevationSources().add(new RasterElevationSource(fs));
                }
                _sceneView.setScene(scene);
            } else if (_mapView != null) {

                ArcGISMap map = new ArcGISMap(
                        new Basemap(tlayer));
                _mapView.setMap(map);
            }

        }

        @Override
        public void addDomLayer(ArrayList<Layer> layers) {
            if (_sceneView != null) {
                _sceneView.getScene().getBasemap().getBaseLayers().addAll(layers);
            } else if (_mapView != null) {
                _mapView.getMap().getBasemap().getBaseLayers().addAll(layers);
            }
        }

        @Override
        public void addDemRasterLayer(ArrayList<Layer> demLayers) {
            if (_sceneView != null) {
                _sceneView.getScene().getBasemap().getReferenceLayers().addAll(demLayers);
            } else if (_mapView != null) {
                _mapView.getMap().getBasemap().getReferenceLayers().addAll(demLayers);
            }
        }

        @Override
        public LayerList getDemRasterLayer() {
            if (_sceneView != null) {
                return _sceneView.getScene().getBasemap().getReferenceLayers();
            } else if (_mapView != null) {
                return _mapView.getMap().getBasemap().getReferenceLayers();
            }
            return null;
        }

        @Override
        public void onMapTouch(OnTouchListener onTouchListener) {
            _onTouchListener = onTouchListener;
        }


        @Override
        public GeoView getGeoView() {
            return _sceneView != null ? _sceneView : _mapView;
        }

        @Override
        public void addRefenceLayer(Layer l) {
            if (_sceneView != null) {
                _sceneView.getScene().getBasemap().getReferenceLayers().add(l);
            } else if (_mapView != null) {
                _mapView.getMap().getBasemap().getReferenceLayers().add(l);
            }
        }

        @Override
        public void adddRefenceLayers(List<FeatureLayer> ls) {

            if (_sceneView != null) {
                _sceneView.getScene().getBasemap().getReferenceLayers().addAll(ls);
            } else if (_mapView != null) {
                _mapView.getMap().getBasemap().getReferenceLayers().addAll(ls);
            }
        }

        @Override
        public void addOptionLayer(FeatureLayer fl) {
            if (_sceneView != null) {
                _sceneView.getScene().getOperationalLayers().add(fl);
            } else if (_mapView != null) {
                _mapView.getMap().getOperationalLayers().add(fl);
            }
        }

        @Override
        public void addOptionLayers(List<FeatureLayer> ls) {
            if (_sceneView != null) {
                _sceneView.getScene().getOperationalLayers().addAll(ls);
            } else if (_mapView != null) {
                _mapView.getMap().getOperationalLayers().addAll(ls);
            }

        }

        @Override
        public LayerList getBaseLayers() {
            if (_sceneView != null) {
                return _sceneView.getScene().getBasemap().getBaseLayers();
            } else if (_mapView != null) {
                return _mapView.getMap().getBasemap().getBaseLayers();
            }
            return null;
        }

        @Override
        public LayerList getRefrenceLayers() {
            if (_sceneView != null) {
                return _sceneView.getScene().getBasemap().getReferenceLayers();
            } else if (_mapView != null) {
                return _mapView.getMap().getBasemap().getReferenceLayers();
            }
            return null;
        }

        @Override
        public LayerList getOperationalLayers() {
            if (_sceneView != null) {
                return _sceneView.getScene().getOperationalLayers();
            } else if (_mapView != null) {
                return _mapView.getMap().getOperationalLayers();
            }
            return null;
        }

        @Override
        public ListenableList<GraphicsOverlay> getGraphicsOverlays() {
            if (_sceneView != null) {
                return _sceneView.getGraphicsOverlays();
            } else if (_mapView != null) {
                return _mapView.getGraphicsOverlays();
            }
            return null;
        }

        //
//        @Override
//        public void addGrobleLayer(ArcGISTiledLayer tlayer) {
//            if(_sceneView!=null){
//                _sceneView.getScene().getBasemap().getBaseLayers().add(tlayer);
//            }
//        }
    }
}
